<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>函数增强-默认参数详细解构</title>
  <!-- 
  在 JavaScript 中，使用默认参数和解构赋值可以使函数更加灵活和易于使用。
  一、默认参数
  默认参数允许你为函数的参数指定默认值，当调用函数时，如果没有传入相应的参数，就会使用这些默认值。

   1. 基本用法
  function greet(name = '世界') {
      console.log(`你好, ${name}!`);
  }

  greet(); // 输出: 你好, 世界!
  greet('小明'); // 输出: 你好, 小明!
  在上面的例子中，如果没有传入  `name`  参数，则使用默认值  `'世界'` 。

   2. 默认参数的顺序
  默认参数应该放在参数列表的末尾，这样可以避免调用时的混淆。
  function example(a, b = 2) {
      console.log(a, b);
  }

  example(1);     // 输出: 1 2
  example(1, 3);  // 输出: 1 3
  如果将默认参数放在前面，可能会导致意想不到的结果：
  function example(b = 2, a) {
      console.log(a, b);
  }

  example(1);     // 输出: undefined 1
  example(1, 3);  // 输出: 3 1
  二、解构赋值与默认参数
  解构赋值允许我们从对象或数组中提取值，并可以为提取的值指定默认值。结合默认参数可以使函数更加灵活。

   1. 对象解构赋值
  function printUser({ name, age = 18 }) {
      console.log(`姓名: ${name}, 年龄: ${age}`);
  }

  printUser({ name: '小明' }); // 输出: 姓名: 小明, 年龄: 18
  printUser({ name: '小红', age: 25 }); // 输出: 姓名: 小红, 年龄: 25
  在这个例子中， `age`  参数有一个默认值  `18` ，如果没有传入  `age` ，则使用默认值。

   2. 数组解构赋值
  function sum([a = 0, b = 0] = []) {
      return a + b;
  }

  console.log(sum([1, 2])); // 输出: 3
  console.log(sum([1]));    // 输出: 1
  console.log(sum());       // 输出: 0
  在这里，数组的解构赋值允许我们为  `a`  和  `b`  设置默认值，同时函数参数本身也有一个默认值  `[]` ，以防没有传入任何参数。

  三、默认参数的计算
  默认参数可以是任何表达式，包括调用其他函数或进行计算。
  function multiply(a, b = a) {
      return a * b;
  }

  console.log(multiply(5)); // 输出: 25
  console.log(multiply(5, 2)); // 输出: 10
  在这个例子中， `b`  的默认值依赖于  `a`  的值。

  四、注意事项
  1. 作用域：默认参数在函数调用时被评估，因此可以访问函数体内的变量。
  let x = 10;

    function example(a, b = x) {
        console.log(a, b);
    }

    example(1); // 输出: 1 10
  2. 与其他参数的结合：可以与其他参数结合使用，但要确保默认参数在参数列表的末尾。

  总结

  - 默认参数使得函数在调用时更加灵活，可以为缺失的参数提供默认值。
  - 解构赋值结合默认参数可以简化代码，使得函数参数的处理更加清晰。
  - 使用默认参数时，注意参数的顺序和作用域，以避免潜在的错误。
  -->
</head>
<body>

  <script>

    // 1. 基本结构回顾
    // const obj = {
    //   name: '小明',
    //   age: 18
    // };
    // const { name, age } = obj;

    // 2. 函数参数的解构赋值
    // function foo({ name, age }) {
    //   console.log(name, age);
    // }

    // foo(obj);

    // 3. 函数参数的解构赋值 + 默认参数
    function foo({ name = '小红', age = 18 } = {}) {
      console.log(name, age);
    }
    foo(); // 输出: 小红 18

    function bar({ name, age} = { name: 'bar', age: 18 }) {
      console.log(name, age);
    }
    bar(); // 输出: bar 18

    function baz({ name = 'baz', age = 18 } = { name: 'baz', age: 18 }) {
      console.log(name, age);
    }
    baz(); // 输出: baz 18
    
  </script>
  
</body>
</html>